package com.dataseek.iot.analysis.manager.controller;

import com.alibaba.fastjson.JSONObject;
import com.dataseek.iot.analysis.manager.service.DataService;
import com.dataseek.iot.analysis.manager.vo.AnalysisVo;
import com.dataseek.iot.analysis.manager.vo.DeviceInfoVo;
import com.dataseek.iot.core.jwt.JwtTokenProvider;
import com.dataseek.iot.core.util.AuthUtil;
import com.dataseek.iot.device.manager.vo.DeviceDetailVo;
import com.dataseek.iot.mysql.entity.*;
import com.dataseek.iot.mysql.mapper.MyUserMapper;
import com.dataseek.iot.mysql.service.impl.*;
import com.dataseek.iot.redis.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.*;

import static com.dataseek.iot.core.constant.DeviceStateConst.*;


/**
 * @author cc
 * @Title: 数据服务接口
 * @Description: 数据服务接口
 * @date 2021/10/1011:55 上午
 * @since 1.0
 */
@RestController
@RequestMapping("/frontPage")
@Api(tags = "首页数据接口")
@Slf4j
public class FrontPageController {

    @Autowired
    DataService dataService;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    UserServiceImpl userService;

    @Autowired
    RoleServiceImpl roleService;

    @Autowired
    DeviceServiceImpl deviceService;

    @Autowired
    AlarmLogServiceImpl alarmLogService;

    @Autowired
    AreaServiceImpl areaService;

    @Autowired
    LineServiceImpl lineService;

    @Autowired
    LocationServiceImpl locationService;


    @Autowired
    JwtTokenProvider jwtTokenProvider;

    @Autowired
    MyUserMapper myUserMapper;


    @Autowired
    RedisUtil redisUtil;

    @Value("${mqtt.username}")
    private String username;

    @Value("${mqtt.password}")
    private String password;

    @Value("${mqtt.url}")
    private String url;

    /**
     * 初始化httpClient
     * @param uri
     * @param method
     * @return
     */
    ResponseEntity<JSONObject> restInit(String uri, HttpMethod method){
        HttpHeaders header = new HttpHeaders();
        String auth = username + ":" + password;
        byte[] authentication = auth.getBytes(StandardCharsets.UTF_8);
        byte[] base64Authentication = Base64Utils.encode(authentication);
        String baseCredential = new String(base64Authentication);
        header.add(HttpHeaders.AUTHORIZATION,  "Basic " + baseCredential);
        header.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        HttpEntity<JSONObject> request = new HttpEntity<JSONObject>(header);
        return restTemplate.exchange(uri, method, request, JSONObject.class);
    }

    /**
     * 设备详情查询
     * @param id
     * @return
     */
    @GetMapping("/deviceDetail/{id}")
    @ApiOperation("设备详情")
    public Mono<DeviceDetailVo> deviceDetails(@PathVariable String id){
       return Mono.just(dataService.deviceDetails(id));
    }


    @GetMapping("/topics")
    @ApiOperation("MQTT 数据统计接口")
    public JSONObject topics(){
        StringBuffer uri = new StringBuffer("http://")
                .append("118.195.176.189")
                .append(":")
                .append("8081")
                .append("/api/v4/clients")
                .append("?")
                .append("_page=1&_limit=10");
        ResponseEntity<JSONObject> result = restInit(uri.toString(), HttpMethod.GET);
        return result.getBody();
    }

    @GetMapping("/deviceInfoList")
    @ApiOperation("根据用户信息查询设备信息列表")
    public Mono<List<DeviceInfoVo>> getDeviceInfoList(ServerWebExchange exchange) {
        String username = AuthUtil.getUsername(exchange,jwtTokenProvider);
        List<DeviceInfoVo> list = dataService.getAllDeviceInfo(username);

        return Mono.just(list);
    }




    @GetMapping("/analysis")
    @ApiOperation("首页数据分析接口")
    public Mono<AnalysisVo>  frontPageAnalysisData(ServerWebExchange exchange) throws Exception {
        //在线设备总数
        Integer onlineDeviceNum = 0;
        //离线设备总数
        Integer offlineDeviceNum = 0;
        //异常设备总数
        Integer alarmDeviceNum = 0;
        //未确认报警
        Integer unconfirmedAlarm = 0;
        String username = AuthUtil.getUsername(exchange,jwtTokenProvider);
        List<Device> totalDevices = new ArrayList<>();
        LoginUser loginUser = userService.selectAllUserDetails(username);
        String roleCode = loginUser.getRoleCode();
        if(roleCode.equals("superAdmin")){
            List<Device> devices =  deviceService.list();
            totalDevices.addAll(devices);
            for(Device d : devices){
               String state = d.getState();
               List<DeviceLog> temp = alarmLogService.getAlarmLog(d.getDeviceCode());
               unconfirmedAlarm += temp.size();
               switch (state){
                   case OFFLINE_CODE:
                       offlineDeviceNum++;
                       break;
                   case ALARM_CODE:
                       alarmDeviceNum++;
                       onlineDeviceNum++;
                       break;
                   case ONLINE_CODE:
                       onlineDeviceNum++;
                       break;
                   default:
                       break;

               }

            }
        }else{
            //获取用户管理的线路信息
            String lineCode = loginUser.getLineCode();
            String[] codes = lineCode.split(",");
            for(String c : codes){
                List<Device> devices = deviceService.getDeviceBylineCode(c);
                totalDevices.addAll(devices);
            }

            for(Device d : totalDevices){
                List<DeviceLog> temp = alarmLogService.getAlarmLog(d.getDeviceCode());
                unconfirmedAlarm += temp.size();
                switch (d.getState()){
                    case ONLINE_CODE:
                        onlineDeviceNum ++;
                        break;
                    case OFFLINE_CODE:
                        offlineDeviceNum ++;
                        break;
                    case ALARM_CODE:
                        onlineDeviceNum ++;
                        alarmDeviceNum ++;
                        break;
                    default:
                        break;

                }
            }
        }


        AnalysisVo analysisVo = new AnalysisVo();
        analysisVo.setUsername(username);
        analysisVo.setTotalDeviceNum(totalDevices.size());
        analysisVo.setOnlineDeviceNum(onlineDeviceNum);
        analysisVo.setOfflineDeviceNum(offlineDeviceNum);
        analysisVo.setAlarmDeviceNum(alarmDeviceNum);
        analysisVo.setUnconfirmedAlarm(unconfirmedAlarm);

        return Mono.just(analysisVo);
    }





}
